﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;

namespace YSUtils.Wpf.Controls
{
	/// <summary>
	/// TextBox control for numbers only.
	/// </summary>
	/// <remarks>
	/// The original idea: 
	/// <a href="http://dedjo.blogspot.com/2007/11/number-only-textbox.html">Tamir Khason.</a>
	/// <para/>
	/// The NumberTextBox control allows enter number only.
	/// </remarks>
	/// <example>
	/// This XAML-code shows how to use NumberTextBox control.
	/// <code>
	/// <Window x:Class="NumberBoxTest.MainWindow"
    ///   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ///   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    ///   Title="MainWindow" Height="350" Width="525"
    ///   xmlns:local="clr-namespace:NumberBoxTest">
    /// <Grid>
    ///    <local:NumberTextBox x:Name="numberTextBoxTest"  Height="23" Width="100"/>
    /// </Grid>
	/// </Window>
	/// </code>
	/// </example>
	public class NumberTextBox : TextBox
	{
		/// <summary>
		/// Checks each input and prevents inputting non number symbols.
		/// </summary>
		/// <param name="e">The event data.</param>
		protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
		{
			e.Handled = !AreAllValidNumericChars(e.Text);
			base.OnPreviewTextInput(e); 
		}

		/// <summary>
		/// Checks, if a text contains number symbols only.
		/// </summary>
		/// <param name="str">A text to check.</param>
		/// <returns>True, if the text contians valid symbols.</returns>
		private bool AreAllValidNumericChars(string str)
        {
            bool ret = true;
            if (str == System.Globalization.NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.CurrencyGroupSeparator |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.CurrencySymbol |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.NegativeSign |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.NegativeInfinitySymbol |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.NumberGroupSeparator |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.PercentDecimalSeparator |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.PercentGroupSeparator |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.PercentSymbol |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.PerMilleSymbol |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.PositiveInfinitySymbol |
                str == System.Globalization.NumberFormatInfo.CurrentInfo.PositiveSign)
                return ret;

            int l = str.Length;
            for (int i = 0; i < l; i++)
            {
                char ch = str[i];
                ret &= Char.IsDigit(ch);
            }

            return ret;
        }
	}
}
